// Copyright (c) 2025 Huawei Technologies Co., Ltd.
// openUBMC is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//         http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
//
// Description: KVM独立客户端接口定义

#ifndef KVM_CLIENT_HPP
#define KVM_CLIENT_HPP

#include <string>
#include "Utils.hpp"
#include "WebSocketClient.hpp"
#include "VmmClient.hpp"
#include "AuthenticationManager.hpp"

// 系统启动项枚举类型定义
enum class BootOption {
    // 无启动介质
    None = 0x00,
    // 硬盘启动
    Hdd,
    // 光驱启动
    Cd,
    // 软驱启动
    Floppy,
    // PXE启动
    Pxe,
    // BIOS设置启动
    BiosSetup
};

// 上下电控制枚举类型定义
enum class PowerControlOption {
    // 上电
    On = 0x00,
    // 强制下电
    ForceOff,
    // 下电
    GracefulShutdown,
    // 强制重启
    ForceRestart,
    // 强制下电再上电
    ForcePowerCycle,
    // 安全下电再上电
    GracefulPowerCycle
};

class KvmClient : public WebSocketClient {
public:
    KvmClient();
    ~KvmClient() override;
    
    void RegisterSendMessageHandler(uint16_t cmdType,
        std::function<std::pair<int, std::vector<uint8_t>>(const std::vector<uint8_t>&)> handler);
    void RegisterRecvMessageHandler(uint16_t cmdType, std::function<void(const std::vector<uint8_t>&)> handler);

    void SetErrorHandler(std::function<void(const std::exception&)> handler);
    void SetCloseHandler(std::function<void(const uint16_t&)> handler);
    void SetLogHandler(std::function<void(const std::string&)> handler);
    void LogMessage(const std::string& message);

    int OpenKvm(const char* host, const char* port,
        const char* userName, const char* password, const char* kvmMode);
    int CloseKvm();

    int GetBootOption(BootOption& option);
    int SetBootOption(BootOption option);
    int PowerControl(PowerControlOption option);

    int OpenVmm(const std::string& filePath, MountType type);
    int CloseVmm();

protected:
    void OnMessage(const std::string& message) override;
    void OnClose(const websocket::close_reason& cr) override;
    void OnError(const std::exception& error) override;

private:
    std::function<void(const std::exception&)> errorHandler_;               // 错误处理回调函数
    std::function<void(const websocket::close_reason&)> closeHandler_;      // 会话关闭处理回调函数
    std::function<void(const std::string&)> logHandler_;                    // 日志处理回调函数
    int KvmClient::CreateSession(const char* host, const char* port,
        const char* userName, const char* password, const char* kvmMode);
    void ProcessConnectRsp(const std::vector<uint8_t>& body);

    std::mutex openKvmMutex_; // 防止 OpenKvm 重入
    std::mutex connectRspMutex_; // 用于同步 OpenKvm 和 ProcessConnectRsp
    std::condition_variable connectRspCv_; // 条件变量，用于等待 ProcessConnectRsp 的结果
    int connectRsp_ = E_ERR; // 存储服务端返回的结果

    std::unique_ptr<AuthenticationManager> authManager_;
    VmmClient vmmClient_; // VMM客户端对象
    bool isConnected_{false};  // 是否连接到KVM
    std::string host_;
    char* token_;
    
    std::unordered_map<uint16_t,
        std::function<std::pair<int, std::vector<uint8_t>>(const std::vector<uint8_t>&)>> sendMessageHandlers_; // 发送消息处理函数容器
    std::unordered_map<uint16_t, std::function<void(const std::vector<uint8_t>&)>> recvMessageHandlers_; // 接收消息处理函数容器
};

#endif  // KVM_CLIENT_HPP